package com.onpositive.knowledge.model.value.audits;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.onpositive.data.IPropertyConstants;
import com.onpositive.semantic.model.api.property.IProperty;

public class CompositeAudit extends AuditSourceContainer implements IUniverseAudit {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	public static final String ID = "composite-audit";

	public CompositeAudit() {

	}
	

	@Override
	public void perform( Iterable<IProperty> properties,Iterable<Object> objects, AbstractAuditResult auditResult ) {
		
		if( !( auditResult instanceof GeneralAuditResult ) )
			return ;
		
		GeneralAuditResult rd=(GeneralAuditResult)auditResult;
		
		
		HashMap<IProperty,GeneralAuditResult> resMap = new HashMap<IProperty, GeneralAuditResult>() ;		
		
		for ( IAudit a : getAudits()) {
			
			if( a instanceof IValueAudit ){
				IValueAudit valueAudit = (IValueAudit)a;
				for( IProperty prop : properties ){

					AbstractAuditResult perform = valueAudit.createAuditResult(prop) ;
					valueAudit.perform( prop, objects, perform);
					if (perform != null && perform.isLooksApplyable()) {
						
						GeneralAuditResult r = resMap.get( prop ) ;
						if( r == null ){
							r = new GeneralAuditResult( prop );
							r.looksApplyable = false;
							resMap.put(prop, r) ;
							rd.addChildAudit( r ) ;
							rd.looksApplyable = true ;
						}
						
						r.suspicious.addAll(perform.suspicious);
						r.addChildAudit(perform);
						r.looksApplyable = true;
					}
				}
			}
			if( a instanceof IUniverseAudit ){
				IUniverseAudit universeAudit = (IUniverseAudit)a;
				AbstractAuditResult perform = universeAudit.createAuditResult() ;
				universeAudit.perform(properties, objects,perform);
				if (perform != null && perform.isLooksApplyable() )
				{
					rd.addChildAudit(perform)					 ;
					rd.looksApplyable = true ;
				}				
			}
		}
//		for( Map.Entry<IProperty,GeneralAuditResult> e : resMap.entrySet() )
//		{
//			rd.addChildAudit( e.getValue() ) ;
//			rd.looksApplyable = true ;
//		}
	}

	private boolean depricated(IProperty prop) {
		
		Boolean depr = prop.getMeta().getSingleValue( IPropertyConstants.CHAR_DEPRICATED_LABEL, Boolean.class, null ) ;
		if( depr == null )
			depr = false ;		
		
		return depr;
	}

	protected ArrayList<IAudit> audits=new ArrayList<IAudit>();

	public boolean add(IAudit e) {
		return audits.add(e);
	}

	public boolean remove(IValueAudit o) {
		return audits.remove(o);
	}

	protected IAudit[] getAudits() {
		return audits.toArray(new IAudit[audits.size()]);
	}

	@Override
	public String getId() {
		return ID;
	}


	public void clearAudits()
	{
		audits.clear() ;
	}
	public void addAudits( List<IAudit> lst )
	{
		if( audits == null )
			audits = new ArrayList<IAudit>() ;
		audits.addAll(lst) ;
	}
	
	@Override
	public AbstractAuditResult createAuditResult() {
		return new GeneralAuditResult( null );
	}


	@Override
	public Set<String> getRequiredAudits() {
		// TODO Auto-generated method stub
		return null;
	}
}
